package com.example.demo.localcache.manager;

import com.example.demo.localcache.AbstractCacheManager;
import com.example.demo.localcache.CacheNameDomain;
import com.example.demo.localcache.constant.CacheNameEnum;
import com.example.demo.localcache.util.CacheMessageUtil;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ******************************************************
 *
 * @author liugh9
 * @version 1.0
 * @classname SysConfigCacheManager
 * @description 系统配置管理器
 *
 *
 *
 * 我这里没有使用Redis作为缓存组件，直接使用的ConcurrentHashMap，
 * 有条件的同学可以替换成Redis，效果会更好。
 *
 * SysConfigCacheManager在继承AbstractCacheManager之后，
 * 需要实现getCacheInfo、loadingCache、getSize、getCacheName四个方法，
 * 其中getCacheName是该缓存处理器的基础信息，为了防止loadingCache出现读写问题，我加了一个可重入锁。
 *
 * 我在例子中没有连接数据库，实际上只要将SysConfigCacheManager的CACHE的数据从数据库读取就可以实现了。
 * 我这里只写了一个SysConfigCacheManager，实际业务中可以写很多个处理器，只要继承AbstractCacheManager即可，
 * 不过要注意getCacheName的名字不要重复了，不然CacheManagerRegistry只会取最新的一个。
 *
 * 最后提醒大家一下，这个是本地缓存哈，不支持分布式的。
 *
 *
 *
 * @date 2024/01/24 15:36
 * <p>
 * ******************************************************
 */
@Component
public class SysConfigCacheManager extends AbstractCacheManager {

    private static final Lock LOCK = new ReentrantLock();

    /**
     * KEY: 自定义
     */
    private static ConcurrentMap<String, Object> CACHE;


    @Override
    protected String getCacheInfo() {
        return CacheMessageUtil.toString(CACHE);
    }

    @Override
    protected void loadingCache() {
        LOCK.lock();
        try {
            CACHE = new ConcurrentHashMap<>();
            CACHE.put("key1","value1");
            CACHE.put("key2","value2");
            CACHE.put("key3","value3");
        } finally {
            LOCK.unlock();
        }

    }

    @Override
    protected long getSize() {
        return null == CACHE ? 0 : CACHE.size();
    }

    @Override
    public CacheNameDomain getCacheName() {
        return CacheNameEnum.SYS_CONFIG;
    }

}
